<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>待办事项列表-组件</title>
    <link rel="stylesheet" href="../lib/bulma.min.css">
    <style>
        .completed-bg {
            background-color: #ccc;
        }
        .completed-text {
            text-decoration: line-through;
        }
    </style>
</head>
<body>
        <div id="app">
                <todo-header></todo-header>
                <todo-input @add="addTodoItem"></todo-input>
                <todo-list
                  v-bind:list="todos"
                  @toggle="toggleTodoItem"
                  @remove="removeTodoItem"
                ></todo-list>
              </div>
            
              <script src="../lib/vue.js"></script>
              <script>
                /* 定义组件 */
                // TodoHeader
                const todoHeaderOptions = {
                  template: `
                    <section class="hero is-primary">
                      <div class="hero-body">
                        <p class="title">
                          待办事项列表
                        </p>
                        <p class="subtitle">
                          今日事，今日毕！
                        </p>
                      </div>
                    </section>
                  `
                }
            
                // TodoInput
                const todoInputOptions = {
                  template: `
                    <div class="field is-grouped container" :style="{marginTop: '12px'}">
                      <p class="control is-expanded">
                        <input
                          class="input"
                          type="text"
                          v-model.trim="inputValue"
                          placeholder="请输入新待办事项"
                          ref="inputRef"
                          @keydown.enter="handleAdd"
                        >
                      </p>
                      <p class="control">
                        <a href="/" class="button is-primary" @click="handleAdd">
                          添加
                        </a>
                      </p>
                    </div>
                  `,
                  data() { // 组件中的 data 要是函数的结构，在函数体内部返回普通对象
                    return {
                      inputValue: ''
                    }
                  },
                  methods: {
                    // 处理添加动作
                    handleAdd(e) {
                      // 阻止超级链接跳转
                      e.preventDefault()
            
                      // 输入框自动获得焦点
                      this.$refs.inputRef.focus()
            
                      // 如果文本框中未输入数据，则结束添加
                      if (!this.inputValue) {
                        return
                      }
            
                      // 触发在父组件中绑定的自定义 add 事件
                      // 在触发事件执行时，传递文本框中获取到的输入数据
                      this.$emit('add', this.inputValue)
            
                      // 清空输入框
                      this.inputValue = ''
                    }
                  }
                }
            
                // TodoItem
                // :class="todo.completed ? 'completed-bg' : ''"
                const todoItemOptions = {
                  template: `
                    <div class="card">
                      <div
                        class="card-content"
                        :class="{'completed-text': todo.completed, 'completed-bg': todo.completed}"
                      >
                        <div class="content">
                          {{ todo.id }} - {{ todo.title }} - {{ todo.completed }}
                        </div>
                      </div>
                      <footer class="card-footer">
                        <a href="#" class="card-footer-item" @click="handleToggle">
                          标记为{{todo.completed ? '未' : '已'}}完成
                        </a>
                        <a href="#" class="card-footer-item" @click="handleRemove">删除</a>
                      </footer>
                    </div>
                  `,
                  props: ['todo'],
                  methods: {
                    handleToggle(e) {
                      e.preventDefault()
                      // 向父组件 todo-list 传递当前项的 id
                      this.$emit('toggleTodo', this.todo.id)
                    },
                    handleRemove(e) {
                      e.preventDefault()
                      // 向父组件 todo-list 传递当前项的 id
                      this.$emit('removeTodo', this.todo.id)
                    }
                  }
                }
            
                // TodoList
                const todoListOptions = {
                  template: `
                    <div class="container">
                      <div class="tabs">
                        <ul>
                          <li class="is-active"><a>所有</a></li>
                          <li><a>已完成</a></li>
                          <li><a>未完成</a></li>
                        </ul>
                      </div>
                      
                      <div class="columns is-multiline is-mobile">
                        <div class="column is-one-quarter" v-for="todo in list">
                          <todo-item
                            :todo="todo"
                            @toggleTodo="handleToggle"
                            @removeTodo="$emit('remove', $event)"
                          ></todo-item>
                        </div>
                      </div>
                    </div>
                  `,
                  components: {
                    'todo-item': todoItemOptions
                  },
                  // 利用 props 字段来声明当前 TodoList 组件可以接收的属性
                  // 当 TodoList 组件实例被创建后，props 中的各属性会被自动
                  // 挂载到 TodoList 组件实例下
                  props: ['list'],
                  methods: {
                    handleToggle(id) {
                      // console.log('接收到的id:', id)
                      // 将接收到的 id 转发给父组件
                      this.$emit('toggle', id)
                    },
                    // handleRemove() {}
                  }
                }
            
                /* 注册组件 */
                Vue.component('todo-header', todoHeaderOptions)
                Vue.component('todo-input', todoInputOptions)
                Vue.component('todo-list', todoListOptions)
            
                // 全局待办事项的编号
                let index = 3
                /* 创建 Vue 根实例 */
                const app = new Vue({
                  el: '#app',
                  data: {
                    // todos 数组中保存所有待办事项的内容
                    todos: [
                      {
                        id: 1, // 编号
                        title: '复习 HTML', // 待办事项内容
                        completed: false // 是否已完成
                      },
                      {
                        id: 2, // 编号
                        title: '学习 Vue', // 待办事项内容
                        completed: true // 是否已完成
                      },
                    ],
                  },
                  methods: {
                    /**
                     * 添加待办事项到 todos 数组中
                     */
                    addTodoItem(title) {
                      this.todos.push({
                        id: index++,
                        title,
                        completed: false
                      })
                    },
                    /**
                     * 修改待办事项完成状态
                     */
                    toggleTodoItem(id) {
                      this.todos.forEach(todo => {
                        if (todo.id === id) {
                          todo.completed = !todo.completed
                        }
                      })
                    },
                    /**
                     * 删除待办事项
                     */
                    removeTodoItem(id) {
                      this.todos = this.todos.filter(todo => todo.id !== id)
                    }
                  }
                })
              </script>
</body>
</html>